#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QTableWidget>
#include <QTableWidgetItem>
#include <QGraphicsView>
#include <QGraphicsItem>
#include <QString>

#include "MyTraceCore.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_CloseBtn_clicked()
{
    close();
}

void MainWindow::on_TraceBtn_clicked()
{
    QString LogStr;

    ui->TraceBtn->setEnabled(false);

    Trace.Routes.clear();
    Trace.ProceedCommandLine(qApp->argc(), qApp->argv(), LogStr);
    ui->LogTextEdit->appendPlainText(LogStr);
    qApp->processEvents();

    bool DoLoop = true;
    while (DoLoop)
    {
        LogStr = "";
        DoLoop = Trace.Trace(LogStr);
        ui->LogTextEdit->appendPlainText(LogStr);
        qApp->processEvents();
    }

    for (int i = 0; i < Trace.Routes.size(); i++)
    {
        QWidget* wTab = new QWidget(ui->MainTabs);
        ui->MainTabs->addTab(wTab, Trace.Routes[i]->TargetHostName);
        wTab->show();
        qApp->processEvents();

        QTableWidget* wTable = new QTableWidget(wTab);
        wTable->setGeometry(8, 8, 431, 271);
        wTable->show();
        qApp->processEvents();

        wTable->setColumnCount(4);
        wTable->horizontalHeader()->resizeSection(0, 35);
        wTable->setHorizontalHeaderItem(0, new QTableWidgetItem("#"));
        wTable->setHorizontalHeaderItem(1, new QTableWidgetItem("IP"));
        wTable->setHorizontalHeaderItem(2, new QTableWidgetItem("Host name"));
        wTable->setHorizontalHeaderItem(3, new QTableWidgetItem("Ping"));
        wTable->setRowCount(Trace.Routes[i]->Hops.size());
        for (int x = 0; x < Trace.Routes[i]->Hops.size(); x++)
        {
            QTableWidgetItem* wiIndex = new QTableWidgetItem(QString::number(x));
            wTable->setItem(x, 0, wiIndex);
            QTableWidgetItem* wiIP = new QTableWidgetItem(Trace.Routes[i]->Hops[x]->HopHostIP);
            wTable->setItem(x, 1, wiIP);
            QTableWidgetItem* wiName = new QTableWidgetItem(Trace.Routes[i]->Hops[x]->HopHostName);
            wTable->setItem(x, 2, wiName);
            QString Ping;
            for (int z = 0; z < Trace.Routes[i]->Hops[x]->HopPingTimes.size(); z++)
            {
                if (Trace.Routes[i]->Hops[x]->HopPingTimes[z] == -1)
                {Ping += "* ";}
                else
                {Ping += QString::number(Trace.Routes[i]->Hops[x]->HopPingTimes[z])+" ";}
            }
            QTableWidgetItem* wiPing = new QTableWidgetItem(Ping);
            wTable->setItem(x, 3, wiPing);
        }
    }

    struct GraphHop
    {
        unsigned long IP;
        int x, y;
    };

    QGraphicsScene* Scene = new QGraphicsScene();
    //Scene->addText("Hello, world!");
    //Scene->addLine(10, 10, 20, 20);

    int MaxRoute = 0;
    for (int i = 0; i < Trace.Routes.count(); i++)
    {
        if (Trace.Routes[i]->Hops.count() > MaxRoute)
        {MaxRoute = Trace.Routes[i]->Hops.count();}
    }

    GraphHop* GraphHops;
    int GraphHopsCount = Trace.Routes.count()*MaxRoute;
    GraphHops = (GraphHop*)malloc(GraphHopsCount*sizeof(GraphHop));
    /*
    for (int i = 0; i < GraphHopsCount; i++)
    {
        GraohHops[i] = new GraphHop;
    }
    */
    memset(GraphHops, 0, GraphHopsCount*sizeof(GraphHop));

    for (int x = 0; x < Trace.Routes.count(); x++)
    {
        for (int y = 0; y < Trace.Routes[x]->Hops.count(); y++)
        {
            bool HopExists = false;
            unsigned long Addr = inet_addr(Trace.Routes[x]->Hops[y]->HopHostIP.toLatin1());
            for (int i = 0; i < GraphHopsCount; i++)
            {
                if (GraphHops[i].IP == Addr)
                {HopExists = true;}
            }
            if (!HopExists)
            {
                for (int z = 0; z < Trace.Routes.count(); z++)
                {
                    if (!GraphHops[y*Trace.Routes.count()+z].IP)
                    {
                        if (z < x)
                        {z = x;}
                        GraphHops[y*Trace.Routes.count()+z].IP = Addr;
                        GraphHops[y*Trace.Routes.count()+z].x = z*(100+25);
                        GraphHops[y*Trace.Routes.count()+z].y = 10+y*(25+25);
                        Scene->addRect(GraphHops[y*Trace.Routes.count()+z].x, GraphHops[y*Trace.Routes.count()+z].y, 100, 20);
                        Scene->addText(inet_ntoa(*(in_addr*)&Addr))->setPos(GraphHops[y*Trace.Routes.count()+z].x, GraphHops[y*Trace.Routes.count()+z].y);
                        break;
                    }
                }
            }
        }
    }

    for (int x = 0; x < Trace.Routes.count(); x++)
    {
        unsigned long PrevHopIP = inet_addr(Trace.Routes[x]->Hops[0]->HopHostIP.toLatin1());
        for (int y = 1; y < Trace.Routes[x]->Hops.count(); y++)
        {
            unsigned long Addr = inet_addr(Trace.Routes[x]->Hops[y]->HopHostIP.toLatin1());
            int PrevHopIndex = 0, HopIndex = 0;
            for (int i = 0; i < GraphHopsCount; i++)
            {
                if (GraphHops[i].IP == Addr)
                {HopIndex = i;}
                if (GraphHops[i].IP == PrevHopIP)
                {PrevHopIndex = i;}
            }

            int LineX1 = GraphHops[PrevHopIndex].x+50;
            int LineY1 = GraphHops[PrevHopIndex].y+20;
            int LineX2 = GraphHops[HopIndex].x+50;
            int LineY2 = GraphHops[HopIndex].y;

            Scene->addLine(LineX1, LineY1, LineX2, LineY2);

            PrevHopIP = Addr;
        }
    }

    QGraphicsView* wGraph = new QGraphicsView(Scene, ui->MainTabs);

    ui->MainTabs->addTab(wGraph, "Graph");
    wGraph->setGeometry(8, 8, 431, 271);
    wGraph->show();
    qApp->processEvents();
}
